/*
 * Configure.java
 *
 * Created on October 13, 2004, 2:41 PM
 * Documents necesary to understand svm_params:
 *                  livsvm/svm_parameter.java sourcecode
 *                  livsvm/README
        * svm_type *
        int C_SVC = 0;
        int NU_SVC = 1;
        int ONE_CLASS = 2;
        int EPSILON_SVR = 3;
        int NU_SVR = 4;

        * kernel_type *
        int LINEAR = 0;
        int POLY = 1;
        int RBF = 2;
        int SIGMOID = 3;

        int svm_type;
        int kernel_type;
        double degree;   // for poly
        double gamma;    // for poly/rbf/sigmoid
        double coef0;    // for poly/sigmoid

        // these are for training only
        double cache_size;   // in MB
        double eps;          // stopping criteria
        double C;            // for C_SVC, EPSILON_SVR and NU_SVR
        int nr_weight;       // for C_SVC
        int[] weight_label;  // for C_SVC
        double[] weight;     // for C_SVC
        double nu;           // for NU_SVC, ONE_CLASS, and NU_SVR
        double p;            // for EPSILON_SVR: loss funtion
        int shrinking;       // use the shrinking heuristics
        int probability;     // do probability estimates
 * 
 *      March 11, 2009. Object renamed from ConfigurePanel to ConfigureSVMPanel
 *
 */

package portfolio.stock;

import java.awt.event.ComponentEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentListener;

import java.sql.*;
import java.util.Vector;
import java.util.Enumeration;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import portfolio.stock.analize.DrawPanel;
import portfolio.mainScreen;
import libsvm.svm_parameter;
import portfolio.stock.analize.AnalizeArguments;
import portfolio.stock.analize.AnalizeButtonAction;
import portfolio.stock.save.SaveExperiment;

/**
 *
 * @author  ACA
 */
public class ConfigureSVMPanel implements ComponentListener //extends JInternalFrame
{
    private mainScreen    fatherFrame;
    private JPanel        jSvmPanel;      //<<<<<
    private JPanel        buttonArea;
    private JButton       jAnalizeButton;
    private JButton       jSaveExperimentButton;
    
    private SelectVariables     selectVariables = null;
    
    private cancelButton        cancel;
    private DrawPanel           DataTrain;
    
    private String              sStockName         = null;
    private Vector              vSelectedVariables = null;
    private JCheckBox           preprocessOK       = null;
    private JTextField          componentsText     = null;
    private ButtonGroup         preprocessGroup    = null;
    private JTextField          iterationsText     = null;
    private ButtonGroup         typeGroup          = null;
    private ButtonGroup         kernelGroup        = null;
    
    private JTextField          degreeText        = null;
    private JTextField          gammaText         = null;
    private JTextField          coef0Text         = null;
    private JTextField          costText          = null;
    private JTextField          nuText            = null;
    private JTextField          elossText         = null;
    private JTextField          etolText          = null;
    private JTextField          shrinkText        = null;
    
    private int                 iXTrainMatrixCols = 0;
    private AnalizeArguments    analizeArguments  = null;
    private AnalizeButtonAction analizeButton     = null;
    private SaveExperiment      saveExperiment    = null;
    /***********************************************************/
    private class cancelButton extends JButton implements ActionListener 
    {
        private ConfigureSVMPanel selectRef;
        /**********************************/
        public cancelButton (ConfigureSVMPanel mainFrameParam) 
        {
            super ("Cancel");
            selectRef    = mainFrameParam;
            this.addActionListener (this);

            return;
        }
        /*******************************************/
        public void actionPerformed(ActionEvent e) 
        {
//ACA            selectRef.dispose ();
            if (DataTrain != null)
//ACA                DataTrain.dispose();
            ;
            return;
        }

    } /* End Class submitButton::selectIndexes::cancelButton */
    /**
     * @param e 
     */
    public void componentResized(ComponentEvent e) {
//        System.out.println ("Component Resized >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    }

    public void componentMoved(ComponentEvent e) {
//        System.out.println ("Component Moved >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    }

    public void componentShown(ComponentEvent e) {
        System.out.println ("Component Shown >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        
        try {
            vSelectedVariables = selectVariables.getSelectVariablesList();
            int iSelectedVariables = vSelectedVariables.size();
            if (iSelectedVariables >= 1) {
                iXTrainMatrixCols = vSelectedVariables.size();
                Integer IComponents = this.getComponentsNumber ();
                componentsText.setText (IComponents.toString());
                if (analizeButton != null) {
                    analizeButton.resetAnalizeButtonAction(this, sStockName, vSelectedVariables);
                } else {
                    analizeButton = new AnalizeButtonAction (fatherFrame, jAnalizeButton, this, sStockName, vSelectedVariables);
                }
                
                if (saveExperiment != null) {
                    saveExperiment.ResetSaveExperiment (sStockName, vSelectedVariables);
                } else {
                    saveExperiment = new SaveExperiment (fatherFrame, jSaveExperimentButton, this, sStockName, vSelectedVariables);
                }

                int iSelectedVariablesLen = vSelectedVariables.size();
                fatherFrame.displayMessage ("portfolio.stock.ConfigureSVMPanel.componentShown 152", "Selected Variables Ln: " + iSelectedVariablesLen + "; SelectedVariables: " + vSelectedVariables.toString());
            } else {
                fatherFrame.displayMessage ("portfolio.stock.ConfigureSVMPanel.componentShown 152", "Empty selected Variables.");
            }
        } catch (Exception ex) {
            fatherFrame.displayMessage("portfolio.stock.ConfigureSVMPanel.componentShown 154", ex.getMessage());
        }
    }

    public void componentHidden(ComponentEvent e) {
        System.out.println ("Component Hidden >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    }
    /**
     * 
     */
    public ConfigureSVMPanel(mainScreen   fatherFrameParam,
                             String       sNameParam,
                             SelectVariables selectVariablesParam,
                             AnalizeArguments analizeArgumentsParam) throws Exception 
    {
        fatherFrame     = fatherFrameParam;
        sStockName      = sNameParam;
        
        if (analizeArgumentsParam == null) {
            analizeArguments = new AnalizeArguments ();
        } else {
            analizeArguments = analizeArgumentsParam;
        }
        selectVariables = selectVariablesParam;
        
        jSvmPanel = fatherFrame.getSVMParamsPanel();
        jSvmPanel.setLayout(new BorderLayout ());
        jSvmPanel.addComponentListener (this);
        
        buttonArea = new JPanel ();
        buttonArea.setLayout (new FlowLayout (FlowLayout.RIGHT));
        //this.getContentPane ().add (buttonArea, BorderLayout.SOUTH);
        jSvmPanel.add (buttonArea, BorderLayout.NORTH);

        jAnalizeButton = new JButton ("Analize");
        buttonArea.add(jAnalizeButton);
        
        jSaveExperimentButton = new JButton ("Save Experiment");
        buttonArea.add (jSaveExperimentButton); //Button);
        
        cancel = new cancelButton (this);
        buttonArea.add (cancel);

        JPanel generalArea = new JPanel ();
        generalArea.setLayout (new BoxLayout (generalArea, BoxLayout.Y_AXIS));
        //this.getContentPane ().add (generalArea, BorderLayout.CENTER);
        jSvmPanel.add(generalArea, BorderLayout.CENTER);


        JPanel trainConfig = new JPanel ();
        trainConfig.setLayout (new FlowLayout ());
        trainConfig.setBorder (BorderFactory.createTitledBorder (new EtchedBorder (Color.white, Color.gray),
                                                              "Stock data."));
        Dimension dStockData = new Dimension ();
        dStockData.setSize(800, 50);
        trainConfig.setMaximumSize(dStockData);
        trainConfig.add (new JLabel (sStockName));
        generalArea.add (trainConfig);

        JPanel preConfig = new JPanel ();
        preConfig.setLayout (new BoxLayout (preConfig, BoxLayout.X_AXIS));
        preConfig.setBorder (BorderFactory.createTitledBorder (new EtchedBorder (Color.white, Color.gray),
                                                              "Preprocess"));
        Dimension dPreprocess = new Dimension ();
        dPreprocess.setSize(800, 50);
        preConfig.setMaximumSize(dPreprocess);
        generalArea.add (preConfig);
        
        boolean preprocess = analizeArguments.getPreprocess();
        preprocessOK = new JCheckBox ("Preprocess?", preprocess);
        preConfig.add (preprocessOK);

        preConfig.add (new JLabel ("  Components?"));
	componentsText = new JTextField (3);
        preConfig.add (componentsText); 
        
        preprocessGroup = new ButtonGroup ();
        JRadioButton pcaPre  = new JRadioButton ("PCA",false);
        preprocessGroup.add (pcaPre);
        preConfig.add (pcaPre);
        
        JRadioButton icaPre = new JRadioButton ("ICA", false);
        preprocessGroup.add (icaPre);        
        preConfig.add (icaPre);
        String sPreprocessType = analizeArguments.preprocess_type;
        if ("PCA".equals(sPreprocessType)){
            pcaPre.setSelected(true);
        } else if ("ICA".equals (sPreprocessType)) {
            icaPre.setSelected(true);
        }
        
        preConfig.add (new JLabel ("  Iterations?"));
        String sIterations = analizeArguments.getIterations(); //null;
	iterationsText = new JTextField (sIterations, 3); //"200", 3);
        preConfig.add (iterationsText);        
        
        JPanel svmConfig = new JPanel ();
        svmConfig.setLayout (new BoxLayout (svmConfig, BoxLayout.Y_AXIS));
        svmConfig.setBorder (BorderFactory.createTitledBorder (new EtchedBorder (Color.white, Color.gray),
                                                              "SVM Regression Attributes"));
        Dimension dSVMRegAttribs = new Dimension ();
        dSVMRegAttribs.setSize (800, 180);
        svmConfig.setMaximumSize(dSVMRegAttribs);
        generalArea.add (svmConfig);
        
        JPanel svmTypKern = new JPanel ();
        svmTypKern.setLayout (new GridLayout (1,2));
        
        JPanel svmType = new JPanel ();
        svmType.setLayout (new GridLayout (1, 5));
        svmType.setBorder (BorderFactory.createTitledBorder (new EtchedBorder (Color.white, Color.gray),
                                                              "SVM Type"));
        typeGroup = new ButtonGroup ();
        JRadioButton csvcTyp  = new JRadioButton ("C-SVC", false); //0
        typeGroup.add (csvcTyp);
        svmType.add (csvcTyp);
        JRadioButton nusvcTyp = new JRadioButton ("nu-SVC", false); //1
        typeGroup.add (nusvcTyp);        
        svmType.add (nusvcTyp);
        
        JRadioButton oneTyp = new JRadioButton ("one-Class", false); //
        typeGroup.add (oneTyp);        
        svmType.add (oneTyp);
                                                                        /////////////0j0 there is a hole here.
        JRadioButton esvrTyp  = new JRadioButton ("eps-SVR", true); //3
        typeGroup.add (esvrTyp);        
        svmType.add (esvrTyp);
        JRadioButton nusvrTyp = new JRadioButton ("nu-SVR", false); //4
        typeGroup.add (nusvrTyp);        
        svmType.add (nusvrTyp); 
        svmTypKern.add (svmType);
        /////////////////////////////////////////////////////////////
        Enumeration typeE = typeGroup.getElements();
        int iType = analizeArguments.svm_type;
        JRadioButton buttonType = null;
        for (int iIdx = 0; iIdx <= iType; iIdx++) {
            if (iIdx > svm_parameter.NU_SVR)
                throw new Exception ("SVM type button group out of range.");
            buttonType = (JRadioButton)typeE.nextElement();
        }
        buttonType.setSelected(true);
        /////////////////////////////////////////////////////////////
        
        JPanel kernelType = new JPanel ();
        kernelType.setLayout (new GridLayout (1, 4));
        kernelType.setBorder (BorderFactory.createTitledBorder (new EtchedBorder (Color.white, Color.gray),
                                                              "Kernel Type"));
        kernelGroup = new ButtonGroup ();
        JRadioButton linearTyp  = new JRadioButton ("Linear",false);
        kernelGroup.add (linearTyp);
        kernelType.add (linearTyp);
        JRadioButton polynomTyp = new JRadioButton ("Polynomial", false);
        kernelGroup.add (polynomTyp);        
        kernelType.add (polynomTyp);
        JRadioButton rbfTyp     = new JRadioButton ("RBF", false); //true);
        kernelGroup.add (rbfTyp);        
        kernelType.add (rbfTyp);
        JRadioButton sigmoidTyp = new JRadioButton ("Sigmoid", false);
        kernelGroup.add (sigmoidTyp);        
        kernelType.add (sigmoidTyp); 
        /////////////////////////////////////////////////////////////
        Enumeration e = kernelGroup.getElements();
        int iKernel = analizeArguments.kernel_type; //.getKErnelType();
        JRadioButton button = null;
        for (int iIdx = 0; iIdx <= iKernel; iIdx++) {
            if (iIdx > svm_parameter.SIGMOID)
                throw new Exception ("Kernel button group out of range.");
            button = (JRadioButton)e.nextElement();
        }
        button.setSelected(true);
        /////////////////////////////////////////////////////////////
        svmTypKern.add (kernelType);  
        
        svmConfig.add (svmTypKern);          
 
        JPanel miscellanea = new JPanel ();
        
        miscellanea.setLayout (new GridLayout (4, 4));
        svmConfig.add (miscellanea); 
        
        //Action here
        miscellanea.add (new JLabel ("Degree"));
        String sDegree = analizeArguments.getDegree(); //null;
	degreeText = new JTextField (sDegree, 3); //"3.0", 3);
        miscellanea.add (degreeText);
        
        miscellanea.add (new JLabel ("Gamma"));
        String sGamma = analizeArguments.getGamma(); //null;
	gammaText = new JTextField (sGamma, 3); //"0", 3);
        miscellanea.add (gammaText);
        
        miscellanea.add (new JLabel ("Coef0"));
        String sCoef0 = analizeArguments.getCoef0(); //null;
	coef0Text = new JTextField (sCoef0, 3); //"0", 3);
        miscellanea.add (coef0Text); 
        
        miscellanea.add (new JLabel ("Cost"));
        String sCost = analizeArguments.getCost(); //null;
	costText = new JTextField (sCost, 3); //"1", 3);
        miscellanea.add (costText);

        miscellanea.add (new JLabel ("Nu"));
        String sNu = analizeArguments.getNu(); //null;
	nuText = new JTextField (sNu, 3); //"0.5", 3);
        miscellanea.add (nuText);

        miscellanea.add (new JLabel ("e-SVR loss"));
        String sEpsilonSVRLoss = analizeArguments.getEpsilonSVRLoss(); //null;
	elossText = new JTextField (sEpsilonSVRLoss, 3); //"0.1", 3);
        miscellanea.add (elossText); 
        
        miscellanea.add (new JLabel ("e tolerance"));
        String sEpsilonTolerance = analizeArguments.getEpsilonTolerance(); //null
	etolText = new JTextField (sEpsilonTolerance, 3); //"0.001", 3);
        miscellanea.add (etolText); 
        
        miscellanea.add (new JLabel ("shrink"));
        if (analizeArguments.shrinking == 1)
            shrinkText = new JTextField ("yes", 3);
        else if (analizeArguments.shrinking == 0)
            shrinkText = new JTextField ("no", 3);
        miscellanea.add (shrinkText); 
        

    } /* End Constructor selectSvmAttributes */
    /**
     * 
     */
    private Integer getComponentsNumber ()
    {
        Integer IComponents = null;
        if (analizeArguments.components == 0) {
            IComponents = new Integer(iXTrainMatrixCols);
            analizeArguments.components = iXTrainMatrixCols;
        } else {
            if (iXTrainMatrixCols > analizeArguments.components) {
                IComponents = new Integer (iXTrainMatrixCols);
            } else {
                IComponents = new Integer (analizeArguments.components);
            }
        }
        
        return IComponents;
    }
    /*************************************************************************/
    public int getComponentsConfig () throws Exception
    {
        int     iLen           = iXTrainMatrixCols; //dXTrainMatrix [0].length;
        Integer iMaxComponents = new Integer (iLen);
        String  sComponents    = componentsText.getText();
        Integer iTmp           = null;
        //double dExit = 0;
        try {
            iTmp = new Integer (sComponents);
        }
        catch (Exception e) {
            componentsText.setText (iMaxComponents.toString());
            throw new Exception (e + "Error: componets value not allowed.");
        }
        int iExit = iTmp.intValue ();
        
        if (iExit < 2 || iExit > iLen) {
            componentsText.setText (iMaxComponents.toString());
            throw new Exception ("Components value not allowed");
        }
        
        return iExit;
    }    
    /*************************************************************************/
    public String getPreprocessGroup ()
    {
        String sPreprocessGroup = null;
        
        for (Enumeration e = preprocessGroup.getElements(); e.hasMoreElements(); ) {
            JRadioButton b = (JRadioButton)e.nextElement();
            if (b.getModel() == preprocessGroup.getSelection()) {
                sPreprocessGroup = b.getText ();
                break;
            }
        }
        if      (sPreprocessGroup == "PCA") {
            return "PCA";
        }
        else if (sPreprocessGroup == "ICA") {
            return "ICA";
        }

        fatherFrame.displayMessage ("ConfigureSVMPanel.getPreprocessGroup 415", "Warning: no preprocess selected; default ICA.");
        return "ICA";
    }
    /*************************************************************************/
    public int getIterationsConfig () throws Exception
    {
        String sIterations = iterationsText.getText();
        Integer iTmp = null;
        //double dExit = 0;
        try {
            iTmp = new Integer (sIterations);
        }
        catch (Exception e) {
            iterationsText.setText ("200");
            throw new Exception (e + "Error: iterations value not allowed.");
        }
        if (iTmp.intValue () < 0) {
            iterationsText.setText ("200");
            throw new Exception ("iterations value not allowed");
        }
        return iTmp.intValue();
    }    
    /*************************************************************************/
    public int getTypeGroup ()
    {
        String sTypeGroup = null;
        
        for (Enumeration e = typeGroup.getElements(); e.hasMoreElements(); ) {
            JRadioButton b = (JRadioButton)e.nextElement();
            if (b.getModel() == typeGroup.getSelection()) {
                sTypeGroup = b.getText ();
                break;
            }
        }
        if      (sTypeGroup == "C-SVC") {
            return svm_parameter.C_SVC;
        }
        else if (sTypeGroup == "nu-SVC") {
            return svm_parameter.NU_SVC;
        }
        else if (sTypeGroup == "one-Class") {
            return svm_parameter.ONE_CLASS;
        }
        else if (sTypeGroup == "eps-SVR") {
            return svm_parameter.EPSILON_SVR;
        }
        else if (sTypeGroup == "nu-SVR") {
            return svm_parameter.NU_SVR;
        }

        return svm_parameter.EPSILON_SVR;
    }
    /*************************************************************************/
    public String getTypeGroupString ()
    {
        String sTypeGroup = null;
        
        for (Enumeration e = typeGroup.getElements(); e.hasMoreElements(); ) {
            JRadioButton b = (JRadioButton)e.nextElement();
            if (b.getModel() == typeGroup.getSelection()) {
                sTypeGroup = b.getText ();
                break;
            }
        }        
        return sTypeGroup;
    }
    /*************************************************************************/
    public int getKernelGroup ()
    {
        String sKernelGroup = null;
        
        for (Enumeration e = kernelGroup.getElements(); e.hasMoreElements(); ) {
            JRadioButton b = (JRadioButton)e.nextElement();
            if (b.getModel() == kernelGroup.getSelection()) {
                sKernelGroup = b.getText ();
                break;
            }
        }
        if      (sKernelGroup == "Linear") {
            return svm_parameter.LINEAR;
        }
        else if (sKernelGroup == "Polynomial") {
            return svm_parameter.POLY;
        }
        else if (sKernelGroup == "RBF") {
            return svm_parameter.RBF;
        }
        else if (sKernelGroup == "Sigmoid") {
            return svm_parameter.SIGMOID;
        }

        return svm_parameter.RBF;
    }
    /*************************************************************************/
    public String getKernelGroupString ()
    {
        String sKernelGroup = null;

        for (Enumeration e = kernelGroup.getElements(); e.hasMoreElements(); ) {
            JRadioButton b = (JRadioButton)e.nextElement();
            if (b.getModel() == kernelGroup.getSelection()) {
                sKernelGroup = b.getText ();
                break;
            }
        }
        return sKernelGroup;
    }
    /*************************************************************************/
    public double getDegreeConfig () throws Exception
    {
        String sDegree = degreeText.getText();
        Double dTmp = null;

        try {
            dTmp = new Double (sDegree);
        }
        catch (Exception e) {
            degreeText.setText ("3.0");
            throw new Exception (e + "Error: degree value not allowed.");
        }
        return dTmp.doubleValue();
    }
    /**************************************************************************/
    public double getGammaConfig () throws Exception
    {
        String sGamma = gammaText.getText();
        Double dTmp = null;

        try {
            dTmp = new Double (sGamma);
        }
        catch (Exception e) {
            gammaText.setText ("0");
            throw new Exception (e + "Error: gamma value not allowed.");
        }
        return dTmp.doubleValue();
    }    
    /**************************************************************************/
    public double getCoef0Config () throws Exception
    {
        String sCoef0 = coef0Text.getText();
        Double dTmp = null;

        try {
            dTmp = new Double (sCoef0);
        }
        catch (Exception e) {
            coef0Text.setText ("0");
            throw new Exception (e + "Error: coef0 value not allowed.");
        }
        return dTmp.doubleValue();
    }
    /**************************************************************************/
    public double getCostConfig () throws Exception
    {
        String sCost = costText.getText();
        Double dTmp = null;
        double dExit = 0;
        try {
            dTmp = new Double (sCost);
            dExit = dTmp.doubleValue ();
            if (dExit <= 0) {
                //JOptionPane.showMessageDialog (null, "Error: cost value not allowed.");
                throw new Exception ("Cost value not allowed");
            }
        }
        catch (Exception e) {
            costText.setText ("1");
            throw new Exception (e + "Error: cost value not allowed.");
        }
        return dExit;
    }
    /**************************************************************************/
    public double getNuConfig () throws Exception
    {
        String sNu = nuText.getText();
        Double dTmp = null;

        try {
            dTmp = new Double (sNu);
        }
        catch (Exception e) {
            nuText.setText ("0.5");
            throw new Exception (e + "Error: nu value not allowed.");
        }
        return dTmp.doubleValue();
    }
    /**************************************************************************/
    public double getElossConfig () throws Exception
    {
        String sEloss = elossText.getText();
        Double dTmp = null;

        try {
            dTmp = new Double (sEloss);
        }
        catch (Exception e) {
            elossText.setText ("0.1");
            throw new Exception (e + "Error: p value not allowed.");
        }
        return dTmp.doubleValue();
    }    
    /**************************************************************************/
    public double getETolConfig () throws Exception
    {
        String sETol = etolText.getText();
        Double dTmp = null;

        try {
            dTmp = new Double (sETol);
        }
        catch (Exception e) {
            etolText.setText ("0.001");
            throw new Exception (e + "Error: p value not allowed.");
        }
        return dTmp.doubleValue();
    }
    /**************************************************************************/
    public void disposeConfigurePanel ()
    {
 //ACA       this.dispose ();
        if (DataTrain != null)
//ACA            DataTrain.dispose();
        ;
        return;
    } /* End method disposeConfigurePanel */
    /**
     * 
     */
    public JCheckBox getPreprocessOK ()
    {
        return preprocessOK;
    }
    /**
     * 
     */
    public JButton getAnalizeButton ()
    {
        return jAnalizeButton;
    }
    /**
     * 
     */
    public Vector getSelectVariablesList ()
    {
        return vSelectedVariables;
    }
    /**************************************************************************/
    public int getShrinking () throws Exception
    {
        String sShrinking = shrinkText.getText(); //elossText.getText();

        try {
            if ("yes".equals(sShrinking))
                return 1; 
            else if ("no".equals(sShrinking))
                return 0;
        }
        catch (Exception e) {
            shrinkText.setText ("1");
            throw new Exception (e + "Error: p value not allowed.");
        }
        return 1; //dTmp.doubleValue();
    }    
} /* End class selectSvmAttributes */
